package com.bkgy.modularbx.coil_track_fullproc.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.anno.Log;
import com.bkgy.commom.model.QueryDTO;
import com.bkgy.modularbx.coil_track_fullproc.domain.TCoilTrackingFullproc;
import com.bkgy.modularbx.coil_track_fullproc.dto.CoilTrackingExportDTO;
import com.bkgy.modularbx.coil_track_fullproc.dto.CoilTrackingQueryDTO;
import com.bkgy.modularbx.coil_track_fullproc.mapper.TCoilTrackingFullprocMapper;
import com.bkgy.modularbx.coil_track_fullproc.service.TCoilTrackingFullprocService;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.ExcelUtilsPOI;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author dell
* @description 针对表【T_COIL_TRACKING_FULLPROC(钢卷分卷全流程表（产线代码：HOT-热轧 TCM2280-酸轧 CAL-连退 CGL1870-镀锌）)】的数据库操作Service实现
*/
@Service
public class TCoilTrackingFullprocServiceImpl extends ServiceImpl<TCoilTrackingFullprocMapper, TCoilTrackingFullproc>
    implements TCoilTrackingFullprocService{

    @Resource
    private TCoilTrackingFullprocMapper coilTrackingFullprocMapper;

    @Resource
    private HttpServletResponse response;

    // 有效产线列表常量
    private static final List<String> VALID_PRODUCTION_LINES = Arrays.asList("TCM2280", "CAL2150", "CAL1630", "CGL1870","RCL2150","RCL1630","RCL1870");

    @Override
    @Log(module = "分卷", description = "分卷全流程列表分页查询")
    public ResultData<CoilTrackingExportDTO> pageCoilTrackingFullproc(QueryDTO<CoilTrackingQueryDTO> queryDTO) {
        //日期格式化
        buildDateParams(queryDTO);
        //分页信息
        Page<TCoilTrackingFullproc> page = new Page<>(queryDTO.getPage().getPageIndex(), queryDTO.getPage().getPageSize());

        LambdaQueryWrapper<TCoilTrackingFullproc> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(
                TCoilTrackingFullproc::getHotCoilId,
                TCoilTrackingFullproc::getTcm2280Extid,
                TCoilTrackingFullproc::getCal2150Extid,
                TCoilTrackingFullproc::getCal1630Extid,
                TCoilTrackingFullproc::getCgl1870Extid,
                TCoilTrackingFullproc::getRewind1Extid,
                TCoilTrackingFullproc::getRewind2Extid,
                TCoilTrackingFullproc::getRewind3Extid,
                TCoilTrackingFullproc::getCreateTime);

        CoilTrackingQueryDTO dto = queryDTO.getDto();

        //构建查询条件
        if (Objects.nonNull(dto)) {
            // 产线多选处理
            if (dto.getProductionLineNumber() != null && !dto.getProductionLineNumber().isEmpty()) {
                // 过滤有效的产线编码
                List<String> validLines = dto.getProductionLineNumber().stream()
                    .filter(StringUtils::hasText)
                    .filter(VALID_PRODUCTION_LINES::contains)
                    .collect(Collectors.toList());

                if (!validLines.isEmpty()) {
                    queryWrapper.and(wrapper -> {
                        for (String line : validLines) {
                            wrapper.or(w -> {
                                switch (line) {
                                    case "TCM2280":
                                        w.isNotNull(TCoilTrackingFullproc::getTcm2280Extid);
                                        if (!StringUtils.isEmpty(dto.getStartDate()) && !StringUtils.isEmpty(dto.getEndDate())) {
                                            w.between(TCoilTrackingFullproc::getTcm2280Toc, dto.getStartDate(), dto.getEndDate());
                                        }
                                        break;
                                    case "CAL2150":
                                        w.isNotNull(TCoilTrackingFullproc::getCal2150Extid);
                                        if (!StringUtils.isEmpty(dto.getStartDate()) && !StringUtils.isEmpty(dto.getEndDate())) {
                                            w.between(TCoilTrackingFullproc::getCal2150Toc, dto.getStartDate(), dto.getEndDate());
                                        }
                                        break;
                                    case "CAL1630":
                                        w.isNotNull(TCoilTrackingFullproc::getCal1630Extid);
                                        if (!StringUtils.isEmpty(dto.getStartDate()) && !StringUtils.isEmpty(dto.getEndDate())) {
                                            w.between(TCoilTrackingFullproc::getCal1630Toc, dto.getStartDate(), dto.getEndDate());
                                        }
                                        break;
                                    case "CGL1870":
                                        w.isNotNull(TCoilTrackingFullproc::getCgl1870Extid);
                                        if (!StringUtils.isEmpty(dto.getStartDate()) && !StringUtils.isEmpty(dto.getEndDate())) {
                                            w.between(TCoilTrackingFullproc::getCgl1870Toc, dto.getStartDate(), dto.getEndDate());
                                        }
                                        break;
                                    case "RCL2150":
                                        w.isNotNull(TCoilTrackingFullproc::getRewind1Extid);
                                        if (!StringUtils.isEmpty(dto.getStartDate()) && !StringUtils.isEmpty(dto.getEndDate())) {
                                            w.between(TCoilTrackingFullproc::getRewind1Toc, dto.getStartDate(), dto.getEndDate());
                                        }
                                        break;
                                    case "RCL1630":
                                        w.isNotNull(TCoilTrackingFullproc::getRewind2Extid);
                                        if (!StringUtils.isEmpty(dto.getStartDate()) && !StringUtils.isEmpty(dto.getEndDate())) {
                                            w.between(TCoilTrackingFullproc::getRewind2Toc, dto.getStartDate(), dto.getEndDate());
                                        }
                                        break;
                                    case "RCL1870":
                                        w.isNotNull(TCoilTrackingFullproc::getRewind3Extid);
                                        if (!StringUtils.isEmpty(dto.getStartDate()) && !StringUtils.isEmpty(dto.getEndDate())) {
                                            w.between(TCoilTrackingFullproc::getRewind3Toc, dto.getStartDate(), dto.getEndDate());
                                        }
                                        break;
                                }
                            });
                        }
                    });
                }
            } else {
                // 没有产线条件，使用默认时间条件
                if (!StringUtils.isEmpty(dto.getStartDate()) && !StringUtils.isEmpty(dto.getEndDate())) {
                    queryWrapper.between(TCoilTrackingFullproc::getCreateTime, dto.getStartDate(), dto.getEndDate());
                }
            }

            // 处理热轧卷号查询条件
            if (StringUtils.hasText(dto.getHotCoilId())) {
                queryWrapper.like(TCoilTrackingFullproc::getHotCoilId, dto.getHotCoilId());
            }

            // 处理钢种类型查询条件
            if (StringUtils.hasText(dto.getSteelgrade())) {
                queryWrapper.like(TCoilTrackingFullproc::getSteelgrade, dto.getSteelgrade());
            }
            // 合同号
            if (StringUtils.hasText(dto.getOrderNo())) {
                queryWrapper.like(TCoilTrackingFullproc::getOrderNo, dto.getOrderNo());
            }
            //跟踪编号
            if (StringUtils.hasText(dto.getTrackIndocnos())) {
                queryWrapper.in(TCoilTrackingFullproc::getIndocno, dto.getTrackIndocnos().split(","));
            }
        }

        //分页查询
        Page<TCoilTrackingFullproc> resultPage = coilTrackingFullprocMapper.selectPage(page, queryWrapper);

        // 将数据转换为导出DTO
        List<CoilTrackingExportDTO> exportDTOList = convertToExportDTO(resultPage.getRecords());

        return ResultData.ResultDataSuccess(exportDTOList,exportDTOList.size(),new BigDecimal(resultPage.getCurrent()),new BigDecimal(resultPage.getTotal()));
    }

    /**
     * 日期格式化
     * @param queryDTO
     */
    private void buildDateParams(QueryDTO<CoilTrackingQueryDTO> queryDTO){
        if (queryDTO.getDto() != null && Objects.nonNull(queryDTO.getDto().getStartDate())
                && Objects.nonNull(queryDTO.getDto().getEndDate())){
                // 获取开始时间和结束时间
            String startDate = queryDTO.getDto().getStartDate();
            String endDate = queryDTO.getDto().getEndDate();
            // 格式化日期
            DateTime startTime = DateUtil.beginOfDay(DateUtil.parseDate(startDate));
            DateTime endTime = DateUtil.endOfDay(DateUtil.parseDate(endDate));
            // 设置开始时间和结束时间
            queryDTO.getDto().setStartDate(startTime.toString());
            queryDTO.getDto().setEndDate(endTime.toString());
        }
    }


    @Override
    public void exportByTemplate(QueryDTO<CoilTrackingQueryDTO> queryDTO) {
        try {
            // 获取数据
            ResultData<CoilTrackingExportDTO> resultData = pageCoilTrackingFullproc(queryDTO);
            if (resultData != null && resultData.getData() != null) {
                List<CoilTrackingExportDTO> exportDTOList = (List<CoilTrackingExportDTO>) resultData.getData();

                // 创建数据模型
                Map<String, Object> dataMap = new HashMap<>();
                // 将转换后的数据放入模型中
                dataMap.put("data", exportDTOList);
                // 获取模板文件
                String templateFileName = "钢卷分卷全流程数据模板.xlsx";

                File file = ResourceUtils.getFile("classpath:exceltemplate/" + templateFileName);
                TemplateExportParams templateExportParams = new TemplateExportParams(file.getPath(), false);
                
                // 创建Workbook
                Workbook workbook = ExcelExportUtil.exportExcel(templateExportParams, dataMap);
                
                // 导出文件名
                String fileName = "钢卷分卷全流程数据";
                
                // 使用工具类导出
                ExcelUtilsPOI.exportExcel(fileName, response, workbook);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("通过模板导出Excel失败: " + e.getMessage(), e);
        }
    }

    /**
     * 将TCoilTrackingFullproc转换为CoilTrackingExportDTO
     * 
     * @param dataList 原始数据列表
     * @return 转换后的导出DTO列表
     */
    private List<CoilTrackingExportDTO> convertToExportDTO(List<TCoilTrackingFullproc> dataList) {
        List<CoilTrackingExportDTO> exportDTOList = new ArrayList<>();
        int serialNumber = 1;
        
        for (TCoilTrackingFullproc entity : dataList) {
            CoilTrackingExportDTO dto = new CoilTrackingExportDTO();
            // 复制基础属性
            BeanUtils.copyProperties(entity, dto);
            
            // 设置序号
            dto.setSerialNumber(serialNumber++);
            
            // 设置产线和出口卷号
            setProductionLineAndExitCoilId(entity, dto);
            
            // 确保时间字段正确设置
            if (entity.getCreateTime() != null) {
                String format = DateUtil.format(dto.getCreateTime(), "yyyy-MM-dd HH:mm:ss");
                dto.setCreateTime(DateUtil.parseDateTime(format));
            }
            
            exportDTOList.add(dto);
        }
        
        return exportDTOList;
    }
    
    /**
     * 设置产线和出口卷号
     * 按照生产顺序判断：
     * 1. 重卷（合并一次、二次、三次重卷）
     * 2. 1870/2150/1630（第二顺序）
     * 3. 2280（第一顺序）
     * 
     * @param entity 原始数据
     * @param dto 导出DTO
     */
    private void setProductionLineAndExitCoilId(TCoilTrackingFullproc entity, CoilTrackingExportDTO dto) {
        // 按照生产顺序判断：重卷 -> 1870/2150/1630 -> 2280
        if (StringUtils.hasText(entity.getRewind1Extid())) {
            // 第三顺序：一次重卷
            dto.setProductionLine("4#重卷");
            dto.setExitCoilId(entity.getRewind1Extid());
            dto.setExitWeight(entity.getRewind1Weight());

            dto.setRewindExtid(entity.getRewind1Extid());
            dto.setRewindWeight(entity.getRewind1Weight());
            dto.setRewindFlag(convertWeightFlag(entity.getRewind1Flag()));
            dto.setRewindYield(entity.getRewind1Yield());
        } else if (StringUtils.hasText(entity.getRewind2Extid())) {
            // 第三顺序：二次重卷
            dto.setProductionLine("5#重卷");
            dto.setExitCoilId(entity.getRewind2Extid());
            dto.setExitWeight(entity.getRewind2Weight());

            dto.setRewindExtid(entity.getRewind2Extid());
            dto.setRewindWeight(entity.getRewind2Weight());
            dto.setRewindFlag(convertWeightFlag(entity.getRewind2Flag()));
            dto.setRewindYield(entity.getRewind2Yield());
        } else if (StringUtils.hasText(entity.getRewind3Extid())) {
            // 第三顺序：三次重卷
            dto.setProductionLine("6#重卷");
            dto.setExitCoilId(entity.getRewind3Extid());
            dto.setExitWeight(entity.getRewind3Weight());

            dto.setRewindExtid(entity.getRewind3Extid());
            dto.setRewindWeight(entity.getRewind3Weight());
            dto.setRewindFlag(convertWeightFlag(entity.getRewind3Flag()));
            dto.setRewindYield(entity.getRewind3Yield());
        }
        else if (StringUtils.hasText(entity.getCgl1870Extid())) {
            // 第二顺序：镀锌1870
            dto.setProductionLine("5#镀锌1870");
            dto.setExitCoilId(entity.getCgl1870Extid());
            dto.setExitWeight(entity.getCgl1870Weight());
        } else if (StringUtils.hasText(entity.getCal2150Extid())) {
            // 第二顺序：连退2150
            dto.setProductionLine("2#连退2150");
            dto.setExitCoilId(entity.getCal2150Extid());
            dto.setExitWeight(entity.getCal2150Weight());
        } else if (StringUtils.hasText(entity.getCal1630Extid())) {
            // 第二顺序：连退1630
            dto.setProductionLine("3#连退1630");
            dto.setExitCoilId(entity.getCal1630Extid());
            dto.setExitWeight(entity.getCal1630Weight());
        } else if (StringUtils.hasText(entity.getTcm2280Extid())) {
            // 第一顺序：酸轧2280
            dto.setProductionLine("3#酸轧2280");
            dto.setExitCoilId(entity.getTcm2280Extid());
            dto.setExitWeight(entity.getTcm2280Weight());
        } else {
            // 默认：热轧
            dto.setProductionLine("热轧");
            dto.setExitCoilId(entity.getHotCoilId());
            dto.setExitWeight(entity.getHotCoilWeight());
        }
        
        // 转换重量异常标记
        dto.setTcm2280WtFlag(convertWeightFlag(entity.getTcm2280WtFlag()));
        dto.setCal2150WtFlag(convertWeightFlag(entity.getCal2150WtFlag()));
        dto.setCal1630WtFlag(convertWeightFlag(entity.getCal1630WtFlag()));
        dto.setCgl1870WtFlag(convertWeightFlag(entity.getCgl1870WtFlag()));

        // 设置损失重量字段
        /*dto.setTcm2280Loss(entity.getTcm2280Loss());
        dto.setCgl1870Loss(entity.getCgl1870Loss());
        dto.setCal2150Loss(entity.getCal2150Loss());
        dto.setCal1630Loss(entity.getCal1630Loss());*/
        // 重卷损失重量优先取有值的那一条
        if (entity.getRewind1Loss() != null) {
            dto.setRewindLoss(entity.getRewind1Loss());
            dto.setRewindYield(entity.getRewind1Yield());
        } else if (entity.getRewind2Loss() != null) {
            dto.setRewindLoss(entity.getRewind2Loss());
            dto.setRewindYield(entity.getRewind2Yield());
        } else if (entity.getRewind3Loss() != null) {
            dto.setRewindLoss(entity.getRewind3Loss());
            dto.setRewindYield(entity.getRewind3Yield());
        } else {
            dto.setRewindLoss(null);
        }
    }
    
    /**
     * 转换重量异常标记
     * 将数据库中的数值转换为显示文本
     * 
     * @param flag 原始标记值
     * @return 转换后的显示文本
     */
    private String convertWeightFlag(String flag) {
        if (flag == null) {
            return null;
        }
        
        switch (flag) {
            case "0":
                return "正常";
            case "1":
                return "超";
            case "-1":
                return "差";
            case "10":
                return "正常(+)";
            default:
                return flag;
        }
    }
}





